import flet as ft
from flet.core.elevated_button import ElevatedButton
from flet.core.types import FontWeight
from fletx.core import (
    FletXPage, FletXWidget, FletXController, RxInt, Reactive, RxStr, RxBool
)
from fletx.decorators import reactive_form, two_way_reactive
from fletx.utils import AppContext

from app.core.utils import (
    route_return, get_window_size
)


@two_way_reactive({  # Enables two way binding allowing ui to change
    'value': 'rx_value',  # reactive object's value
    'visible': 'rx_visible',  # (like Angular two way data binding system)
    'disabled': 'rx_disabled'  # value <--> rx_value
})
class ReactiveTextField(ft.TextField):
    """Example of two way Reactive TextField"""

    def __init__(
            self,
            rx_value: RxStr = RxStr(""),
            rx_visible: RxBool = RxBool(True),
            rx_disabled: RxBool = RxBool(False),
            **kwargs
    ):
        # Define reactive properties
        self.rx_value = rx_value
        self.rx_visible = rx_visible
        self.rx_disabled = rx_disabled

        super().__init__(**kwargs)


@reactive_form(
    form_fields={
        'host': 'rx_host',
        'port': 'rx_port',
        'user': 'rx_user',
        'password': 'rx_password',
        'target_db': 'rx_target_db'
    },
    validation_rules={
        'host': lambda x: len(x) >= 3
    },
)
class PortalAddForm(ft.Column):
    """Portal Add Form"""
    rx_host = Reactive('')
    rx_port = Reactive('')
    rx_user = Reactive('')
    rx_password = Reactive('')
    rx_target_db = Reactive('')

    def __init__(self):
        super().__init__(spacing=20, expand=True, )

    def build(self):
        """Build form Controls."""

        self.controls = [
            ft.Text("Portal Add From", size=24, weight=FontWeight.BOLD),

            ReactiveTextField(
                label="DB Host",
                rx_value=self.rx_host
            ),

            ReactiveTextField(
                label="Port",
                rx_value=self.rx_port
            ),
            ElevatedButton(
                text="Register for free",
                on_click=lambda _: self.submit(),
                disabled=lambda: not self.rx_is_valid.value
            ),

        ]


class PagePortalEditor(ft.BottomSheet):
    """Portal Editor"""
    doc_width: Reactive = Reactive(400.00)

    def __init__(self):
        super().__init__(
            open=False,
            content=self.build()
        )

    def build(self):
        return ft.Container(
            expand=True,
            width=self.doc_width,
            content=ft.Column(
                spacing=20,
                expand=True,
                alignment=ft.MainAxisAlignment.START,
                horizontal_alignment=ft.CrossAxisAlignment.CENTER,
                controls=[
                    ft.Text("Portal Editor"),
                    ft.Container(
                        width=self.doc_width,
                        padding=ft.padding.all(20),
                        height=400,
                        expand=True,
                        content=PortalAddForm()
                    )
                ]
            ))


class PagePortal(FletXPage):
    bs = PagePortalEditor()

    def build(self):
        return ft.Pagelet(
            expand=True,
            content=ft.Column(
                spacing=20,
                alignment=ft.MainAxisAlignment.START,
                horizontal_alignment=ft.CrossAxisAlignment.CENTER,
                controls=[
                    ft.Row(
                        alignment=ft.MainAxisAlignment.START,
                        controls=[
                            ft.IconButton(
                                icon=ft.Icons.ARROW_BACK,
                                on_click=lambda e: route_return(e)
                            ),
                            ft.IconButton(
                                icon=ft.Icons.ADD,
                                on_click=lambda e: self.open_editor(e)
                            )
                        ]
                    ),
                    ft.Text("Portal")
                ]
            )
        )

    def open_editor(self, e: ft.ControlEvent):
        win_width, win_height = get_window_size(e)
        self.bs.doc_width.value = win_width * 0.96
        e.page.open(self.bs)
        pass
